// Solver released by written permission from Jacob Mattingley, for non-commercial use only
/* Produced by CVXGEN, 2018-08-30 09:34:39 -0400.  */
/* CVXGEN is Copyright (C) 2006-2017 Jacob Mattingley, jem@cvxgen.com. */
/* The code in this file is Copyright (C) 2006-2017 Jacob Mattingley. */
/* CVXGEN, or solvers produced by CVXGEN, cannot be used for commercial */
/* applications without prior written permission from Jacob Mattingley. */

/* Filename: util.c. */
/* Description: Common utility file for all cvxgen code. */
#include "solver.h"
#include <time.h>
#include <stdlib.h>
#include <math.h>
long global_seed = 1;
static clock_t tic_timestart;
void tic(void)
{
  tic_timestart = clock();
}
float toc(void)
{
  clock_t tic_timestop;
  tic_timestop = clock();
  printf("time: %8.2f.\n", (float)(tic_timestop - tic_timestart) / CLOCKS_PER_SEC);
  return (float)(tic_timestop - tic_timestart) / CLOCKS_PER_SEC;
}
float tocq(void)
{
  clock_t tic_timestop;
  tic_timestop = clock();
  return (float)(tic_timestop - tic_timestart) / CLOCKS_PER_SEC;
}
void printmatrix(char *name, double *A, int m, int n, int sparse)
{
  int i, j;
  printf("%s = [...\n", name);
  for (i = 0; i < m; i++)
  {
    for (j = 0; j < n; j++)
      if ((sparse == 1) && (A[i + j * m] == 0))
        printf("         0");
      else
        printf("  % 9.4f", A[i + j * m]);
    printf(",\n");
  }
  printf("];\n");
}
double unif(double lower, double upper)
{
  return lower + ((upper - lower) * rand()) / RAND_MAX;
}
/* Next function is from numerical recipes in C. */
#define IA 16807
#define IM 2147483647
#define AM (1.0 / IM)
#define IQ 127773
#define IR 2836
#define NTAB 32
#define NDIV (1 + (IM - 1) / NTAB)
#define EPS 1.2e-7
#define RNMX (1.0 - EPS)
float ran1(long *idum, int reset)
{
  int j;
  long k;
  static long iy = 0;
  static long iv[NTAB];
  float temp;
  if (reset)
  {
    iy = 0;
  }
  if (*idum <= 0 || !iy)
  {
    if (-(*idum) < 1)
      *idum = 1;
    else
      *idum = -(*idum);
    for (j = NTAB + 7; j >= 0; j--)
    {
      k = (*idum) / IQ;
      *idum = IA * (*idum - k * IQ) - IR * k;
      if (*idum < 0)
        *idum += IM;
      if (j < NTAB)
        iv[j] = *idum;
    }
    iy = iv[0];
  }
  k = (*idum) / IQ;
  *idum = IA * (*idum - k * IQ) - IR * k;
  if (*idum < 0)
    *idum += IM;
  j = iy / NDIV;
  iy = iv[j];
  iv[j] = *idum;
  if ((temp = AM * iy) > RNMX)
    return RNMX;
  else
    return temp;
}
/* Next function is from numerical recipes in C. */
float randn_internal(long *idum, int reset)
{
  static int iset = 0;
  static float gset;
  float fac, rsq, v1, v2;
  if (reset)
  {
    iset = 0;
  }
  if (iset == 0)
  {
    do
    {
      v1 = 2.0 * ran1(idum, reset) - 1.0;
      v2 = 2.0 * ran1(idum, reset) - 1.0;
      rsq = v1 * v1 + v2 * v2;
    } while (rsq >= 1.0 || rsq == 0.0);
    fac = sqrt(-2.0 * log(rsq) / rsq);
    gset = v1 * fac;
    iset = 1;
    return v2 * fac;
  }
  else
  {
    iset = 0;
    return gset;
  }
}
double randn(void)
{
  return randn_internal(&global_seed, 0);
}
void reset_rand(void)
{
  srand(15);
  global_seed = 1;
  randn_internal(&global_seed, 1);
}
